home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 4 / FM Towns Free Software Collection 4 - Disc 1.iso / t_os / helper / source / dir.c < prev    next >
Text File  |  1991-10-18  |  9KB  |  428 lines

  1. /***********************************
  2.  
  3.     Dir & File Select
  4.  
  5. **********************************/
  6. #include    <stdio.h>
  7. #include    <stdlib.h>
  8. #include    <string.h>
  9. #include    <ctype.h>
  10. #include    <msdos.cf>
  11. #include    "dir.h"
  12.  
  13. #define TRUE        1
  14. #define FALSE        0
  15. #define ERR        (-1)
  16.  
  17. static struct {
  18.     unsigned char    dd_dmy[21];
  19.     unsigned char    dd_att;
  20.     unsigned short int    dd_time,dd_date;
  21.     unsigned long    dd_size;
  22.     char        dd_name[14];
  23. } dma;
  24.  
  25. extern int    errno;
  26.  
  27. char    *strdup();
  28.  
  29. static int dos_err_chk(void)
  30. {
  31.     if ( (Registers.Flags & 0x0001) != 0 ) {
  32.     errno = Registers.AX.R;
  33.     return ERR;
  34.     } else
  35.     return FALSE;
  36. }
  37. int    chdrv(int no)
  38. {
  39.     Registers.AX.R = 0x0E00;
  40.     Registers.DX.R = no;
  41.     calldos();
  42.     return dos_err_chk();
  43. }
  44. int    mkdir(char *name)
  45. {
  46.     Registers.AX.R = 0x3900;
  47.     Registers.DX.R = (int)name;
  48.     Registers.DS.R = getds();
  49.     calldos();
  50.     return dos_err_chk();
  51. }
  52. int    rmdir(char *name)
  53. {
  54.     Registers.AX.R = 0x3A00;
  55.     Registers.DX.R = (int)name;
  56.     Registers.DS.R = getds();
  57.     calldos();
  58.     return dos_err_chk();
  59. }
  60. int    chdir(char *name)
  61. {
  62.     Registers.AX.R = 0x3B00;
  63.     Registers.DX.R = (int)name;
  64.     Registers.DS.R = getds();
  65.     calldos();
  66.     return dos_err_chk();
  67. }
  68. int    getdrv(void)
  69. {
  70.     Registers.AX.R = 0x1900;
  71.     calldos();
  72.     if ( dos_err_chk() != 0 )
  73.     return ERR;
  74.     return (Registers.AX.R & 0xFF);
  75. }
  76. int    getdir(char *name)
  77. {
  78.     *(name++) = '\\';
  79.     Registers.AX.R = 0x4700;
  80.     Registers.DX.R = 0x0000;
  81.     Registers.SI.R = (int)name;
  82.     Registers.DS.R = getds();
  83.     calldos();
  84.     if ( dos_err_chk() )
  85.     *name = '\0';
  86.     return dos_err_chk();
  87. }
  88. int    getattr(char *name)
  89. {
  90.     Registers.AX.R = 0x4300;
  91.     Registers.DX.R = (int)name;
  92.     Registers.DS.R = getds();
  93.     calldos();
  94.     if ( dos_err_chk() )
  95.     return ERR;
  96.     return Registers.CX.R;
  97. }
  98. int    isdir(char *file)
  99. {
  100.     int     at;
  101.  
  102.     if ( (at = getattr(file)) == ERR )
  103.     return FALSE;
  104.  
  105.     return ((at & 0x10) != 0 ? TRUE:FALSE);
  106. }
  107. static char    *subname(register char *name)
  108. {
  109.     char    *p;
  110.  
  111.     if ( strcmp(name,".") == 0 ||
  112.      strcmp(name,"..") == 0 ||
  113.      (p = strrchr(name,'.')) == NULL )
  114.     while ( *name != '\0' ) name++;
  115.     else
  116.     name = p + 1;
  117.     return name;
  118. }
  119. static int     dir_cmp(DIRECT *sp,DIRECT *dp)
  120. {
  121.     int     cd;
  122.  
  123.     if ( IS_DIR(sp) != IS_DIR(dp) )
  124.     return IS_DIR(sp) ? ERR:TRUE;
  125.     if ( (cd = strcmp(subname(sp->d_name),subname(dp->d_name))) != 0 )
  126.     return cd;
  127.     return strcmp(sp->d_name,dp->d_name);
  128. }
  129. static DIRECT  *dir_sort(DIRECT *sp,DIRECT *dp)
  130. {
  131.     register DIRECT *tp;
  132.     DIRECT tmp;
  133.  
  134.     tp = &tmp;
  135.     if ( (tp->d_next = sp) == NULL )
  136.     return dp;
  137.     while ( tp->d_next != NULL ) {
  138.     if ( dir_cmp(tp->d_next,dp) >= 0 )
  139.         break;
  140.     tp = tp->d_next;
  141.     }
  142.     dp->d_next = tp->d_next;
  143.     tp->d_next = dp;
  144.     return tmp.d_next;
  145. }
  146. static DIRECT  *dir_apend(DIRECT *sp,DIRECT *dp)
  147. {
  148.     register DIRECT *tp;
  149.     DIRECT tmp;
  150.  
  151.     tp = &tmp;
  152.     if ( (tp->d_next = sp) == NULL )
  153.     return dp;
  154.     while ( tp->d_next != NULL )
  155.     tp = tp->d_next;
  156.     dp->d_next = tp->d_next;
  157.     tp->d_next = dp;
  158.     return tmp.d_next;
  159. }
  160. static DIRECT  *dir_get(char *dir,int sw)
  161. {
  162.     register DIRECT  *np;
  163.     DIRECT  *tp=NULL;
  164.  
  165.     Registers.AX.R = 0x1A00;
  166.     Registers.DX.R = (int)&dma;
  167.     Registers.DS.R = getds();
  168.     calldos(); 
  169.  
  170.     Registers.AX.R = 0x4E00;
  171.     Registers.CX.R = 0x31;
  172.     Registers.DX.R = (int)dir;
  173.     Registers.DS.R = getds();
  174.     calldos();
  175.  
  176.     if ( (Registers.Flags & 0x0001) != 0 )
  177.     return NULL;
  178.  
  179.     do {
  180.     if ( (sw == FALSE || (dma.dd_att & 0x10) != 0) &&
  181.          strcmp(dma.dd_name,".") != 0 ) {
  182.  
  183.         if ( (np = (DIRECT *)
  184.                malloc(sizeof(DIRECT)+strlen(dma.dd_name))) == NULL )
  185.         break;
  186.  
  187.         np->d_next = np->d_child = NULL;
  188.         np->d_att  = dma.dd_att;
  189.         np->d_time = dma.dd_time;
  190.         np->d_date = dma.dd_date;
  191.         np->d_size = dma.dd_size;
  192.         strcpy(np->d_name,dma.dd_name);
  193.         tp = dir_sort(tp,np);
  194.     }
  195.     Registers.AX.R = 0x4F00;
  196.     calldos();
  197.     } while ( (Registers.Flags & 0x0001) == 0 );
  198.  
  199.     return tp;
  200. }
  201.  
  202. /*******************************************
  203. static DIRECT  *dir_map(char *dir,int sw)
  204. {
  205.     FILE    *fp;
  206.     register DIRECT  *np;
  207.     DIRECT  *tp=NULL;
  208.     char    *p;
  209.     char    tmp[BUFSIZ];
  210.  
  211.     if ( (p = strchr(dir,'\\')) == NULL )
  212.     p = dir;
  213.  
  214.     if ( (p = strrchr(p,'.')) == NULL ||
  215.      strcmp(p,".QQQ") != 0 ||
  216.      (fp = fopen(dir,"r")) == NULL )
  217.     return dir_get(dir,sw);
  218.  
  219.     while ( fgets(tmp,BUFSIZ,fp) != NULL ) {
  220.     if ( (p = strchr(tmp,'\n')) != NULL )
  221.         *p = '\0';
  222.  
  223.     if ( tmp[0] == '\0' || tmp[0] == '#' )
  224.         continue;
  225.  
  226.     if ( (np = (DIRECT *)malloc(sizeof(DIRECT)+strlen(tmp))) == NULL )
  227.         break;
  228.  
  229.     np->d_next = np->d_child = NULL;
  230.     np->d_att  = 0;
  231.     strcpy(np->d_name,tmp);
  232.     tp = dir_apend(tp,np);
  233.     }
  234.  
  235.     fclose(fp);
  236.     return tp;
  237. }
  238. ************************************************/
  239.  
  240. DIR    *opendir(char *dir)
  241. {
  242.     DIR     *dirp;
  243.  
  244.     if ( (dirp = (DIR *)malloc(sizeof(DIR))) != NULL )
  245.     dirp->dd_top = dirp->dd_now = dir_get(dir,FALSE);
  246.  
  247.     return dirp;
  248. }
  249. DIRECT    *readdir(DIR *dirp)
  250. {
  251.     DIRECT *np;
  252.  
  253.     if ( (np = dirp->dd_now) != NULL )
  254.     dirp->dd_now = np->d_next;
  255.     return np;
  256. }
  257. void    seekdir(DIR *dirp,int n)
  258. {
  259.     DIRECT *np;
  260.  
  261.     np = dirp->dd_top;
  262.     while ( n-- > 0 && np != NULL )
  263.     np = np->d_next;
  264.     dirp->dd_now = np;
  265. }
  266. int    countdir(DIR *dirp)
  267. {
  268.     int    i;
  269.     DIRECT *np;
  270.  
  271.     i = 0;
  272.     np = dirp->dd_top;
  273.     while ( np != NULL ) {
  274.     i++;
  275.     np = np->d_next;
  276.     }
  277.     return i;
  278. }
  279. void    closedir(DIR *dirp)
  280. {
  281.     DIRECT *np,*tp;
  282.  
  283.     np = dirp->dd_top;
  284.     while ( np != NULL ) {
  285.     tp = np->d_next;
  286.     free(np);
  287.     np = tp;
  288.     }
  289.     free(dirp);
  290. }
  291. char    *joint_path(char *dir,char *file)
  292. {
  293.     int     n;
  294.     char    *p;
  295.  
  296.     p = dir;
  297.     while ( *p != '\0' ) p++;
  298.     if ( p != dir && *(p-1) != ':' && *(p-1) != '\\' )
  299.     strcat(dir,"\\");
  300.     strcat(dir,file);
  301.     return dir;
  302. }
  303. char    *file_serch(char *dir,char *wild)
  304. {
  305.     DIR     *dirp;
  306.     DIRECT  *dp;
  307.     char    tmp[256];
  308.  
  309.     strcpy(tmp,dir);
  310.     joint_path(tmp,wild);
  311.  
  312.     if ( (dirp = opendir(tmp)) == NULL )
  313.     return NULL;
  314.  
  315.     if ( (dp = readdir(dirp)) == NULL ) {
  316.     closedir(dirp);
  317.     return NULL;
  318.     }
  319.  
  320.     strcpy(tmp,dir);
  321.     joint_path(tmp,dp->d_name);
  322.     closedir(dirp);
  323.  
  324.     return strdup(tmp);
  325. }
  326. /********************
  327.  
  328. DIRECT    *alldir(char *dir)
  329. {
  330.     DIRECT *tp;
  331.     DIRECT *np;
  332.     char   tmp[128];
  333.  
  334.     tp = np = dir_get(dir,TRUE);
  335.     while ( np != NULL ) {
  336.     if ( IS_DIR(np) ) {
  337.         sprintf(tmp,"%s\\%s",dir,np->d_name);
  338.         np->d_child = alldir(tmp);
  339.     }
  340.     np = np->d_next;
  341.     }
  342.     return tp;
  343. }
  344. void    allclose(DIRECT *np)
  345. {
  346.     DIRECT *tp;
  347.  
  348.     while ( np != NULL ) {
  349.     tp = np->d_next;
  350.     if ( IS_DIR(np) )
  351.         allclose(np->child);
  352.     free(np);
  353.     np = tp;
  354.     }
  355. }
  356.  
  357. typedef struct _DIRP {
  358.     struct _DIRP    *next;
  359.     char        *nes;
  360.     char        *dir;
  361. } DIRPTR;
  362.  
  363. char    *strdup(char *str);
  364.  
  365.        DIRPTR    *dir_top=NULL;
  366. static DIRPTR    *dir_btm=NULL;
  367.  
  368. void    dir_tree(char *nes,char *dir,DIRECT *np)
  369. {
  370.     DIRPTR  *dp;
  371.     char    *p,*s;
  372.  
  373.     for ( p = nes ; *p != '\0' ; p++ );
  374.     for ( s = dir ; *s != '\0' ; s++ );
  375.     while ( np != NULL ) {
  376.     sprintf(tmp,"%s\x1b%c\x1b\x95%s",nes,
  377.             (np->d_next == NULL ? '\x9A':'\x93'),np->d_name);
  378.     strcpy(p,np->d_next == NULL ? "   ":"\x1b\x96  ");
  379.     sprintf(s,"\\%s",np->d_name);
  380.     if ( (dp = (DIRPTR *)malloc(sizeof(DIRPTR))) != NULL ) {
  381.         dp->next = NULL;
  382.         dir_btm->next = dp;
  383.         dir_btm = dp;
  384.  
  385.         dp->nes = strdup(tmp);
  386.         dp->dir = strdup(dir);
  387.     }
  388.     dir_tree(nes,dir,np->child);
  389.     *p = '\0';
  390.     *s = '\0';
  391.     np = np->d_next;
  392.     }
  393. }
  394. void    chengdir(int drive)
  395. {
  396.     DIRECT *tp;
  397.     DIRPTR *np;
  398.     char   nes[128];
  399.     char   dir[128];
  400.  
  401.     sprintf(dir,"%c:",drive+'A');
  402.     tp = alldir(dir);
  403.  
  404.     if ( (np = dir_top) != NULL ) {
  405.     do {
  406.         dir_top = np->next;
  407.         free(np->nes);
  408.         free(np->dir);
  409.         free(np);
  410.         np = dir_top;
  411.     } while ( np != NULL );
  412.     }
  413.  
  414.     if ( (dp = (DIRPTR *)malloc(sizeof(DIRPTR))) != NULL ) {
  415.     sprintf(dir,"%c:\\",drive+'A');
  416.     strcpy(nes,"  ");
  417.     dir_top = dir_btm = dp;
  418.     dp->next = NULL;
  419.     dp->nes = strdup(dir);
  420.     dp->dir = strdup(dir);
  421.     dir_tree(nes,dir,tp);
  422.     }
  423.  
  424.     allclose(tp);
  425. }
  426.  
  427. ******************/
  428.